package com.zbkj.admin.service.impl;

import cn.hutool.core.util.BooleanUtil;
import com.zbkj.admin.model.req.SFExpressRouteSubscribeReq;
import com.zbkj.admin.service.SFExpressRouteService;
import com.zbkj.admin.vo.SFExpressRouteVo;
import com.zbkj.dal.base.enums.*;
import com.zbkj.dal.common.utils.JsonUtil;
import com.zbkj.dal.config.AsyncCompletableFuture;
import com.zbkj.dal.dao.ExpressTraceMapper;
import com.zbkj.dal.entity.ba.Share;
import com.zbkj.dal.entity.express.ExpressTrace;
import com.zbkj.dal.entity.order.Order;
import com.zbkj.dal.entity.order.OrderInvoice;
import com.zbkj.service.manager.ShareProfitManager;
import com.zbkj.service.service.*;
import com.zbkj.service.service.order.OrderRentRecordService;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.event.TransactionalEventListener;
import org.springframework.transaction.support.TransactionTemplate;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SFExpressRouteServiceImpl implements SFExpressRouteService {


    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderStatusService orderStatusService;
    @Autowired
    private ShareProfitManager shareProfitManager;
    @Autowired
    private ExpressTraceMapper expressTraceMapper;
    @Autowired
    private OrderInvoiceService orderInvoiceService;
    @Autowired
    private OrderRentRecordService orderRentRecordService;
    @Autowired
    private MerchantOrderService merchantOrderService;
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private ShareService shareService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SFExpressRouteVo sfRouteSubscribe(SFExpressRouteSubscribeReq req) {
        log.info("消费物流信息推送: {}", JsonUtil.toJSONString(req));
        List<SFExpressRouteSubscribeReq.WaybillRoute> waybillRoute = req.getBody().getWaybillRoute();
        if (CollectionUtils.isEmpty(waybillRoute)) {
            return SFExpressRouteVo.success();
        }
        try {
            final LocalDateTime now = LocalDateTime.now();
            waybillRoute.forEach(it -> {
                ExpressTrace expressTrace = new ExpressTrace();
                expressTrace.setAcceptAddress(it.getAcceptAddress());
                expressTrace.setMailNo(it.getMailno());
                expressTrace.setReasonName(it.getReasonName());
                expressTrace.setOrderId(it.getOrderid());
                expressTrace.setAcceptTime(it.getAcceptTime());
                expressTrace.setRemark(it.getRemark());
                expressTrace.setOpCode(it.getOpCode());
                expressTrace.setChannelId(it.getId());
                expressTrace.setReasonCode(it.getReasonCode());
                expressTrace.setCreateTime(now);
                expressTrace.setUpdateTime(now);
                expressTraceMapper.insert(expressTrace);
            });
        } catch (Exception e) {
            log.error("接收物流轨迹失败, 原数据:{}", JsonUtil.toJSONString(req), e);
            return SFExpressRouteVo.error();
        } finally {
            Set<String> collect = waybillRoute.stream().map(SFExpressRouteSubscribeReq.WaybillRoute::getMailno).collect(Collectors.toSet());
            eventPublisher.publishEvent(new ExpressTraceUpdateEventListenerDTO(collect));
        }
        return SFExpressRouteVo.success();
    }

    @TransactionalEventListener(value = ExpressTraceUpdateEventListenerDTO.class)
    public void processTrace(ExpressTraceUpdateEventListenerDTO trackingNumbers) {
        if (CollectionUtils.isEmpty(trackingNumbers.getTrackingNumber())) {
            return;
        }
        trackingNumbers.getTrackingNumber().forEach(trackingNumber -> AsyncCompletableFuture.runAsyncAndNoticeOnError(() -> processTrace(trackingNumber)));
    }

    private void processTrace(String trackingNumber) {
        OrderInvoice orderInvoice = orderInvoiceService.findByTrackingNumber(trackingNumber);
        if (Objects.isNull(orderInvoice)) {
            log.error("更新物流状态失败, 物流单号:{}", trackingNumber);
            return;
        }
        // 更新之后物流的状态
        OrderInvoceStatus orderInvoceStatus = orderInvoiceService.updateOrderInvoiceStatusOnExpressTraceUpdate(trackingNumber);
        if (Objects.isNull(orderInvoceStatus)) {
            log.error("获取最新物流轨迹失败, 物流单号:{}", trackingNumber);
            return;
        }
        log.info("处理物流订单状态 : {}", JsonUtil.toJSONString(orderInvoice));
        // 依据这个状态去更新订单状态
        switch (orderInvoceStatus) {
            // 等待揽收
            case WAITING:
                break;
            // 已揽收
            case COLLECTED:
                // 如果是承享归还的订单，从揽收开始记录
                if (Objects.equals(ExpressOrderType.RENT_RETURN.name(), orderInvoice.getExpressOrderType())) {
                    // 如果是承享订单，开始设置【eb_order_rent_record】开始承享日期
                    Order order = orderService.getByOrderNo(orderInvoice.getOrderNo());
                    // 更新为待贝贝奢护收货状态
                    order.setStatus(OrderStatusEnums.RENT_WAIT_RECEIVE.getCode());
                    orderService.updateById(order);
                    orderStatusService.createLog(order.getPlatOrderNo(), OrderStatusChangeType.ORDER_STATUS_USER_RETURN.getCode(), "归还订单揽收");
                }
                // 如果是供享的初评收货
                else if (Objects.equals(ExpressOrderType.SHARED_INITIAL_EVALUATION_RCV.name(), orderInvoice.getExpressOrderType())) {
                    // 更新订单子状态为，运输中
                    shareService.updateSubStatusByOrderNo(orderInvoice.getOrderNo(), BizSharedOrderStatus.SubStatus.EXPRESS_TRANSPORTATION);
                } else if (Objects.equals(ExpressOrderType.SHARED_CANCEL.name(), orderInvoice.getExpressOrderType())) {
                    shareService.updateSubStatusByOrderNo(orderInvoice.getOrderNo(), BizSharedOrderStatus.SubStatus.RETURNED_EXPRESS_TRANSPORTATION);
                }
                break;
            // 运输中
            case TRANSIT:
                break;
            // 派送中
            case DELIVERY:
                break;
            // 已完成
            case COMPLETED:
                // 买入订单，更新成已完成

                // 承享订单

                break;
            // 已签收
            case SIGNED:
                // 如果是供享单
                if (Objects.equals(ExpressOrderType.SHARED_INITIAL_EVALUATION_RCV.name(), orderInvoice.getExpressOrderType())) {
                    Share share = shareService.getByOrderNo(orderInvoice.getOrderNo());
                    if (Objects.nonNull(share)) {
                        // 设置为已经签收，待贝贝奢护估价阶段
                        share.setStatus(BizSharedOrderStatus.PENDING_VALUATION.name());
                        share.setSubStatus(BizSharedOrderStatus.SubStatus.ASSESSMENT_EXPRESS_SIGN.name());
                        shareService.updateByEntity(share);
                    }
                    break;
                }
                if (Objects.equals(ExpressOrderType.SHARED_CANCEL.name(), orderInvoice.getExpressOrderType())) {
                    Share share = shareService.getByOrderNo(orderInvoice.getOrderNo());
                    if (Objects.nonNull(share)) {
                        // 设置为已经签收，待贝贝奢护估价阶段
//                        share.setStatus(BizSharedOrderStatus.VALUATION.name());
                        share.setSubStatus(BizSharedOrderStatus.SubStatus.RETURNED_EXPRESS_SIGN.name());
                        shareService.updateByEntity(share);
                    }
                    break;
                }
                // 如果是其他订单，开始设置【eb_order_rent_record】开始承享日期
                Order order = orderService.getByOrderNo(orderInvoice.getOrderNo());
                // 更新订单的状态
                if (Objects.equals(OrderType.RENT.getCode(), order.getType())) {
                    // 本次的签收是，承享订单买入的签收， 只需要标记订单状态结果即可
                    if (Objects.equals(ExpressOrderType.RENT_CREATE.name(), orderInvoice.getExpressOrderType())) {
                        // 更新成用户待收货
                        order.setStatus(OrderStatusEnums.RENT_AWAIT_DELIVERY.getCode());
                        orderStatusService.createLog(order.getPlatOrderNo(), OrderStatusChangeType.ORDER_STATUS_SIGN.getCode(), "用户物流签收");
                    }
                    // 本次的签收是，承享订单归还的签收， 标记为贝贝奢护验收中
                    if (Objects.equals(ExpressOrderType.RENT_RETURN.name(), orderInvoice.getExpressOrderType())) {
                        // 更新成贝贝奢护验收中
                        order.setStatus(OrderStatusEnums.RENT_SCRAPY_VERIFY.getCode());
                        orderStatusService.createLog(order.getPlatOrderNo(), OrderStatusChangeType.ORDER_STATUS_USER_RETURN_PLAT_SIGN.getCode(), "平台物流签收");
                    }
                }
                // 购买订单
                else if (Objects.equals(OrderType.PURCHASE.getCode(), order.getType())) {
                    orderStatusService.createLog(order.getPlatOrderNo(), OrderStatusChangeType.ORDER_STATUS_SIGN.getCode(), "用户物流签收");
//                    order.setStatus(OrderStatusEnums.TAKE_DELIVERY.code());
                }
                orderService.updateById(order);
                break;
            // 异常
            case ERROR:
                break;
            // 取消
            case CANCEL:
                break;
            // 转寄中
            case REROUTING:
                break;

            default:
                break;
        }
    }

    @Data
    @NoArgsConstructor
    public class ExpressTraceUpdateEventListenerDTO {

        private Collection<String> trackingNumber;

        public ExpressTraceUpdateEventListenerDTO(Collection<String> trackingNumber) {
            this.trackingNumber = trackingNumber;
        }
    }
}
